package org.campuscontent.io;

import java.beans.DefaultPersistenceDelegate;
import java.beans.Encoder;
import java.beans.ExceptionListener;
import java.beans.Expression;
import java.beans.PersistenceDelegate;
import java.beans.XMLEncoder;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.campuscontent.model.AutomataModel;
import org.campuscontent.ui.AutomataChameleonView;
import org.campuscontent.ui.AutomataGraph;
import org.campuscontent.ui.EdgeMaskView;
import org.jgraph.graph.DefaultEdge;
import org.jgraph.graph.DefaultGraphModel;
import org.jgraph.graph.DefaultPort;
import org.jgraph.graph.EdgeView;
import org.jgraph.graph.GraphConstants;
import org.jgraph.graph.GraphLayoutCache;
import org.jgraph.graph.PortView;

public class AutomataEncoder extends XMLEncoder
{
    public AutomataEncoder( OutputStream out )
    {
        super( out );

        configureEncoder();
    }

    public void configureEncoder()
    {
        // Better debugging output, in case you need it
        setExceptionListener( new ExceptionListener()
        {
            public void exceptionThrown( Exception e )
            {
                e.printStackTrace();
            }
        } );

        setPersistenceDelegate( DefaultGraphModel.class, new DefaultPersistenceDelegate( new String[] { "roots", "attributes" } ) );
        setPersistenceDelegate( AutomataModel.class, new DefaultPersistenceDelegate( new String[] { "roots", "attributes" } ) );

        // Note: In the static initializer the marquee handler of the
        // MyGraph class is made transient to avoid being written out.
        setPersistenceDelegate( AutomataGraph.class, new DefaultPersistenceDelegate( new String[] { "model", "graphLayoutCache" } ) );

        setPersistenceDelegate( GraphLayoutCache.class, new DefaultPersistenceDelegate( new String[] { "model", "factory", "cellViews", "hiddenCellViews", "partial" } ) );

        // setPersistenceDelegate(DefaultGraphCell.class,
        // new DefaultPersistenceDelegate(new String[] { "userObject" }));
        setPersistenceDelegate( DefaultEdge.class, new DefaultPersistenceDelegate( new String[] { "userObject" } ) );
        setPersistenceDelegate( DefaultPort.class, new DefaultPersistenceDelegate( new String[] { "userObject" } ) );
        // setPersistenceDelegate(AbstractCellView.class,
        // new DefaultPersistenceDelegate(new String[] { "cell",
        // "attributes" }));

        setPersistenceDelegate( AutomataChameleonView.class, new DefaultPersistenceDelegate( new String[] { "cell" } ) );
        setPersistenceDelegate( EdgeMaskView.class, new DefaultPersistenceDelegate( new String[] { "cell" } ) );
        setPersistenceDelegate( EdgeView.class, new DefaultPersistenceDelegate( new String[] { "cell" } ) );
        setPersistenceDelegate( PortView.class, new DefaultPersistenceDelegate( new String[] { "cell" } ) );
        setPersistenceDelegate( DefaultEdge.DefaultRouting.class, new PersistenceDelegate()
        {
            protected Expression instantiate( Object oldInstance, Encoder out )
            {
                return new Expression( oldInstance, GraphConstants.class, "getROUTING_SIMPLE", null );
            }
        } );
        setPersistenceDelegate( DefaultEdge.LoopRouting.class, new PersistenceDelegate()
        {
            protected Expression instantiate( Object oldInstance, Encoder out )
            {
                return new Expression( oldInstance, GraphConstants.class, "getROUTING_DEFAULT", null );
            }
        } );
        setPersistenceDelegate( ArrayList.class, getPersistenceDelegate( List.class ) );
    }

}
